package com.goudan.rabbitmq.support;

import com.goudan.rabbitmq.constant.QueueDefinition;
import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;

@Slf4j
@Component
@ConditionalOnProperty(prefix = "spring.rabbitmq", name = "publisher-returns", havingValue = "true")
public class MessageReturnCallBack implements RabbitTemplate.ReturnCallback {

    @Resource
    private RabbitTemplate rabbitTemplate;

    @PostConstruct
    public void init() {
        rabbitTemplate.setReturnCallback(this);
    }

    /**
     * 可以将消息传递过程中不可达到目的地(队列)的消息返回给生产者
     * 只有不可达 才会回退消息
     * 请注意!!!如果你使用了延迟队列插件，那么一定会调用该callback方法，因为数据并没有提交上去，
     * 而是提交在交换器中，过期时间到了才提交上去，并非是bug！你可以用if进行判断交换机名称来捕捉该报错
     */
    @Override
    public void returnedMessage(@NonNull Message message, int replyCode,
                                @NonNull String replyText, String exchange, @NonNull String routingKey) {
        if (exchange.equals(QueueDefinition.LGD_DELAYED_EXCHANGE)) {
            return;
        }
        log.info("消息{}，被交换机{}退回，退回原因：{}，路由Key：{}", new String(message.getBody()), exchange, replyText, routingKey);
    }
}
